package com.zjkwdy.thBgm;

import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

public class BgmPlayActivity extends AppCompatActivity {

    private thfmt fmt;
    private bgmdat dat;
    private thcmt cmt;
    private thbgm NowPlaying = null;

    private String title;
    private Spinner bgmChoose;
    private SeekBar speedSeekBar;
    private SeekBar volSeekBar;
    private TextView speedView;
    private TextView volumeView;
    private TextView cmtView;
    private SeekBar playProgress;
    private Button playButton;
    private Button stop_btn;
    private Switch canRequestAudioFocusSwitch;

    private boolean canRequestAudioFocus = true;
    private boolean paused;

    private boolean playStatusChangedByUser = true; /*除去播放以外的用户操作*/
    private AudioFocusRequest audioFocusRequest;
    private AudioManager.OnAudioFocusChangeListener afListener = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        final String fmtName = intent.getStringExtra(constConfig.EXTRA_FMT_NAME);
        final String datName = intent.getStringExtra(constConfig.EXTRA_DAT_NAME);
        final String cmtName = intent.getStringExtra(constConfig.EXTRA_CMT_NAME);
        this.title = intent.getStringExtra(constConfig.EXTRA_GRP_NAME);
//        Log.d("Extras:",fmtName+datName+cmtName);
        initView();
        this.stop_btn.setEnabled(false);
        Timer progressUpdater = new Timer();
        progressUpdater.schedule(new progressUpdateTask(), 0, 1000);
        /*Long-press to copy*/
        registerHeadsetReceiver(); /*        this.playProgress.setOnSeekBarChangeListener(new onPercentChange());*/
        registerListeners();
        try {
            loadBinary(fmtName, datName, cmtName);
            ArrayAdapter<String> adapterNames = new ArrayAdapter<>(this, R.layout.support_simple_spinner_dropdown_item, this.fmt.bgmNameList);
            bgmChoose.setAdapter(adapterNames);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onBackPressed() {
        stop(this.stop_btn);
        super.onBackPressed();
        finish();
    }

    private void initView() {
        setContentView(R.layout.bgm_play_activity);
        this.bgmChoose = findViewById(R.id.bgmChoose);
        this.playButton = findViewById(R.id.play_btn);
        this.speedSeekBar = findViewById(R.id.playSpeed);
        this.speedView = findViewById(R.id.speedView);
        this.volSeekBar = findViewById(R.id.playVolume);
        this.volumeView = findViewById(R.id.VolumeView);
        this.playProgress = findViewById(R.id.playProgress);
        this.playProgress.setEnabled(false);
        this.cmtView = findViewById(R.id.cmtText);
        this.stop_btn = findViewById(R.id.stop_btn);
        this.canRequestAudioFocusSwitch = findViewById(R.id.requestAudioFocusSwitch);
        setTitle(this.title);
    }

    private void loadBinary(String fmtName, String datName, String cmtName) throws IOException {
        this.fmt = new thfmt(fmtName);
        this.dat = new bgmdat(datName);
        this.cmt = new thcmt(cmtName);
    }

    private void registerHeadsetReceiver() {
        HeadsetPlugReceiver headsetReceiver = new HeadsetPlugReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.intent.action.HEADSET_PLUG");
        registerReceiver(headsetReceiver, intentFilter);
    }

    private boolean requestAudioFocus(boolean request) {
        final String LOG_TAG = "requestAudioFocus";
        Log.d(LOG_TAG, "requestAudioFocus " + request);
        AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        if (afListener == null) afListener = new onAudioFocusChangeListener();
        if (!request && (audioFocusRequest != null)) {
            Log.d(LOG_TAG, "abandonAudioFocus");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { /*一定是用户操作使得取消*/
                playStatusChangedByUser = true;
                audioManager.abandonAudioFocusRequest(audioFocusRequest);
                audioFocusRequest = null;
            } else audioManager.abandonAudioFocus(afListener);
            return true;
        }
        if (audioFocusRequest != null) { /*早就申请成功*/
            return true;
        }
        AudioAttributes playbackAttributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build();
        int requestResult;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
                    .setAudioAttributes(playbackAttributes)
                    .setAcceptsDelayedFocusGain(true)
                    .setOnAudioFocusChangeListener(afListener)
                    .build();
            requestResult = audioManager.requestAudioFocus(audioFocusRequest);
        } else
            requestResult = audioManager.requestAudioFocus(afListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
        boolean result = (requestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
        Log.d(LOG_TAG, "requestAudioFocusResult " + result);
        return result;
    }

    private void registerListeners() {
        this.cmtView.setOnLongClickListener(view -> {
            copyText(((TextView) view).getText().toString());
            return false;
        });
        this.cmtView.setMovementMethod(ScrollingMovementMethod.getInstance());//过长支持滑动
        playButton.setOnClickListener(view -> {
            if (NowPlaying == null || paused) {
                playStatusChangedByUser = !canRequestAudioFocus;
                start();
            } else {
                pause();
                requestAudioFocus(false);
            }
        });
        canRequestAudioFocusSwitch.setOnCheckedChangeListener((ignored,b)->{
                playStatusChangedByUser = !b;
                canRequestAudioFocus = b;
        });
        speedSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                speedView.setText(Integer.valueOf(progress).toString() + "%");
                float speed = (float) progress / 100;
                setSpeed(speed);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                float speed = (float) seekBar.getProgress() / 100;
                Log.d("SPEED", Float.valueOf(speed).toString()); /*setSpeed(speed);*/
            }
        });
        volSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                volumeView.setText(Integer.valueOf(progress).toString() + "%");
                float vol = (float) progress / 100;
                setVolume(vol);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                float vol = (float) seekBar.getProgress() / 100;
                Log.d("VOLUME", Float.valueOf(vol).toString()); /*setSpeed(speed);*/
            }
        });
        bgmChoose.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                flushCMT(getBgmFileName());
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }

    private class progressUpdateTask extends TimerTask {
        @Override
        public void run() {
            if (NowPlaying == null) return;
            try {
                setPlayProgress(NowPlaying.getNowPercent());
            } catch (Exception ignored) {
            }
        }

    }

    private String getBgmFileName() {
        return bgmChoose.getSelectedItem().toString();
    }

    private void copyText(String str) {
        ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
        clipboardManager.setPrimaryClip(ClipData.newPlainText("", str));
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2)
            Toast.makeText(getApplicationContext(), getString(R.string.copySuccess), Toast.LENGTH_SHORT).show();
    }

    public void start() {
        requestAudioFocus(true);
        String choicesBgmName = getBgmFileName();
        this.NowPlaying = fmt.bgmMap.get(choicesBgmName);
        flushCMT(choicesBgmName);
        this.stop_btn.setEnabled(true);
        this.playButton.setText(R.string.button_pause);
        this.NowPlaying.setPlayThread(dat);
        setSpeed(getSpeed());
        setVolume(getVolume());
        paused = false;
    }

    public void stop(View view) {
        if (this.NowPlaying == null) return;
        this.playStatusChangedByUser = true;
        requestAudioFocus(false);
        this.NowPlaying.stop();
        this.NowPlaying = null;
        this.playButton.setText(R.string.button_play);
        stop_btn.setEnabled(false);
        setPlayProgress(0);
    }

    public void pause() {
        if (this.NowPlaying == null) return;
        this.NowPlaying.pause();
        this.playButton.setText(R.string.button_play);
        paused = true;
    }

    private void flushCMT(String bgmFileName) {
        String CMT = this.cmt.getCMT(bgmFileName.split("\\.")[0]);
        this.cmtView.setText(CMT);
    }

    private float getSpeed() {
        Integer progress = speedSeekBar.getProgress();
        float speed = (float) progress / 100;
        speedView.setText(progress + "%");
        return speed;
    }

    private float getVolume() {
        Integer progress = volSeekBar.getProgress();
        float vol = (float) progress / 100;
        volumeView.setText(progress + "%");
        return vol;
    }

    public void setSpeed(float speed) {
        if (this.NowPlaying == null) return;
        this.NowPlaying.setSpeed(speed);
    }

    public void setVolume(float vol) {
        if (this.NowPlaying == null) return;
        this.NowPlaying.setVol(vol);
    }
    private void setPlayProgress(int progress) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            playProgress.setProgress(progress,true);
        } else {
            playProgress.setProgress(progress);
        }
    }
//    class onPercentChange implements SeekBar.OnSeekBarChangeListener {
//        @Override public void
//        onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//            if(!fromUser){
//                return;
//            }
//            setPos((float) progress/100);
//        }
//
//        @Override
//        public void onStartTrackingTouch(SeekBar seekBar) {
//
//        }
//
//        @Override
//        public void onStopTrackingTouch(SeekBar seekBar) {
//            float vol = (float)seekBar.getProgress()/100;
//            Log.d("Percent",Float.valueOf(vol).toString());
//            //setSpeed(speed);
//        }
//      }
    class HeadsetPlugReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (!intent.hasExtra("state")) {
                return;
            }
            int state = intent.getIntExtra("state", 0);
            if (state == 0) {
                /*                Toast.makeText(context,"拔出",Toast.LENGTH_LONG).show();*/
                pause();
            }
        }
    }

    class onAudioFocusChangeListener implements AudioManager.OnAudioFocusChangeListener {
        @Override
        public void onAudioFocusChange(int i) {
            if (playStatusChangedByUser) {
                return;
            }
            if (i != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                pause();
                playStatusChangedByUser = false;
            } else {
                SystemClock.sleep(500);
                start();
            }
        }
    }
}